Skip to content

feat(rpc): finalize SyncChainMmr gRPC endpoint#2075

Merged
kkovaacs merged 4 commits into
nextfrom
krisztian/rpc-sync-mmr-remove-arbitrary-block-number-target
May 15, 2026
Merged

feat(rpc): finalize SyncChainMmr gRPC endpoint#2075
kkovaacs merged 4 commits into
nextfrom
krisztian/rpc-sync-mmr-remove-arbitrary-block-number-target

Conversation

@kkovaacs
Copy link
Copy Markdown
Contributor

@kkovaacs kkovaacs commented May 14, 2026

Based on the discussion in PR #2069 and issue #2044 we've converged on some smaller changes to the SyncChainMmr endpoint.

Changes made to the current interface:

  • Removal of the arbitrary block number sync target. Clients can now choose which finality level they'd like to reach but always sync up to the chain tip (proven or committed).
  • We now return the validator signature for the chain tip block header in the response.

The proposed protobuf interface (implemented by this PR) is the following:

// Finality level we'd like to sync up to.
enum FinalityLevel {
    FINALITY_LEVEL_UNSPECIFIED = 0;
    // Sync up to the latest committed block (chain tip).
    FINALITY_LEVEL_COMMITTED = 1;
    // Sync up to the latest proven block.
    FINALITY_LEVEL_PROVEN = 2;
}

// Chain MMR synchronization request.
message SyncChainMmrRequest {
    // Block number from which to synchronize (inclusive). Set this to the last block
    // already present in the caller's MMR so the delta begins at the next block.
    fixed32 current_block_height = 1;

    // Sync target: either the committed or the proven tip.
    FinalityLevel finality_level = 2;
}

// Represents the result of syncing chain MMR.
message SyncChainMmrResponse {
    // For which block range the MMR delta is returned.
    BlockRange block_range = 1;

    // Data needed to update the partial MMR from `request.block_range.current_block_height + 1` to
    // the sync target.
    primitives.MmrDelta mmr_delta = 2;

    // Block header for the sync target.
    blockchain.BlockHeader block_header = 3;

    // Validator signature for the sync target.
    blockchain.BlockSignature block_signature = 4;
}

Closes #2044

@kkovaacs kkovaacs force-pushed the krisztian/rpc-sync-mmr-remove-arbitrary-block-number-target branch from 22c2bad to e76a4b9 Compare May 14, 2026 08:11
@kkovaacs kkovaacs marked this pull request as ready for review May 14, 2026 08:11
Comment thread crates/rpc/src/server/api.rs Outdated
Comment thread crates/store/src/db/mod.rs Outdated
Comment thread crates/store/src/server/rpc_api.rs
@kkovaacs kkovaacs force-pushed the krisztian/rpc-sync-mmr-remove-arbitrary-block-number-target branch from 3e162ee to 7b6e616 Compare May 14, 2026 09:24
@kkovaacs kkovaacs requested a review from SantiagoPittella May 14, 2026 13:23
Copy link
Copy Markdown
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! I left one small comment inline.

Comment thread crates/store/src/db/models/queries/block_headers.rs
@kkovaacs kkovaacs force-pushed the krisztian/rpc-sync-mmr-remove-arbitrary-block-number-target branch from 89d9bfa to 04bfe3e Compare May 15, 2026 11:03
@kkovaacs kkovaacs merged commit 426d4b5 into next May 15, 2026
19 checks passed
@kkovaacs kkovaacs deleted the krisztian/rpc-sync-mmr-remove-arbitrary-block-number-target branch May 15, 2026 11:10
Copy link
Copy Markdown
Collaborator

@igamigo igamigo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review. Implementation looks great but noticed very small doc inconsistencies while reading through the changes

Comment thread proto/proto/rpc.proto
// Data needed to update the partial MMR from `request.block_range.block_from + 1` to
// `response.block_range.block_to` or the chain tip.

// Data needed to update the partial MMR from `request.block_range.current_block_height + 1` to
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Probably should just be request.current_block_height + 1

Comment thread proto/proto/rpc.proto
CHAIN_TIP_UNSPECIFIED = 0;
// Finality level we'd like to sync up to.
enum FinalityLevel {
FINALITY_LEVEL_UNSPECIFIED = 0;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we clarify here or elsewhere that choosing "unspecified" falls back to committed? There's a small ambiguity in the docs because the request proto comment says "either the committed or the proven tip" which does not cover the unspecified flow either

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc UNSPECIFIED usually means you did not specify and therefore the server is free to do whatever it wants.

Comment thread proto/proto/rpc.proto
Comment on lines 483 to +485
// Block number from which to synchronize (inclusive). Set this to the last block
// already present in the caller's MMR so the delta begins at the next block.
fixed32 block_from = 1;

// Upper bound for the block range. Determines how far ahead to sync.
oneof upper_bound {
// Sync up to this specific block number (inclusive), clamped to the committed chain tip.
fixed32 block_num = 2;
// Sync up to a chain tip variant (committed or proven).
ChainTip chain_tip = 3;
}
fixed32 current_block_height = 1;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think a potentially better name is current_sync_height or maybe current_client_block_height. Also not from this PR but not sure "(inclusive)" here is correct? It's not really part of the response, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think removing "(inclusive)" would make sense.

Regarding the rename -- I think current_sync_height is not really precise (I'd definitely include block in the name).

I'm fine either with the current name or current_client_block_height as well -- I like the latter because it makes it explicit that it's the client state that is communicated in that field.

data_directory: PathBuf,
iterations: usize,
concurrency: usize,
block_range_size: u32,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this was removed but doc comments were not updated to reflect this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SyncChainMmr block range start is exclusive

4 participants